#define _POSIX_SOURCE
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/shm.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include "defines.h"
#include "libproceso.h"
#include "libpcb.h"

#ifndef __LIBTABLA__
#define __LIBTABLA__
 
typedef struct {
	int pid;
	int state;
	int inMemory;
	char name[300];
	time_t timestamp;
	Proceso * proc;
} PCB;

typedef struct {
   PCB* _data;
   int _cantMaxElementos;
   int _shmem;
   sem_t* _mutex;
   char* _sem_name;
} Tabla;

//Crea tabla de procesos en memoria compartida
//Recibe: Puntero a tabla y cantidad maxima de procesos
int crearTabla(Tabla* tabla, int cantMaxElementos);

//Abre la tabla de memoria compartida
//Recibe: Puntero a tabla, cantidad maxima de elementos y id de memoria compartida
int abrirTabla(Tabla* tabla, int cantMaxElementos, int shmem);

//Borra la tabla
void borrarTabla(Tabla* tabla);

//Inserta un nuevo proceso en la tabla
//Recibe: Puntero a la tabla y el comando o nombre del programa
//Devuelve: Ok ? Pid : -1
int insertarProceso(Tabla* tabla, const char * path);

//Cambia el estado de un proceso
//Recibe: Puntero a la tabla, pid del proceso y el nuevo estado
int cambiarEstado(Tabla * tabla, int pid, int state);

//Borra un proceso de la tabla
//Recibe: Puntero a la tabla y pid del proceso
int borrarProceso(Tabla * tabla, int pid);

//Obtiene el estado actual de un proceso
//Recibe: Puntero a la tabla y pid del proceso
int getState(Tabla * tabla, int pid);

//Obtiene el nombre de un proceso
//Recibe: Puntero a la tabla y pid del proceso
char * getName(Tabla * tabla, int pid);

//Obtiene el estado de memoria (suspendido o no) de un proceso
//Recibe: Puntero a la tabla y pid del proceso
int enMemoria(Tabla * tabla, int pid);

//Cambia el estado de memoria (suspendido o no) de un proceso
//Recibe: Puntero a la tabla, pid del proceso y el nuevo estado de memoria
int cambiarEstadoMemoria(Tabla * tabla, int pid, int inMemory);

//Crea el Proceso con su codigo, variables, etc
//Recibe: Puntero a la tabla, pid del proceso y puntero al codigo del proceso
void setProcesoCodigo(Tabla * tabla, int pid, Proceso * p);

//Retorna un puntero al codigo del proceso
//Recibe: Puntero a la tabla, pid del proceso
Proceso * getProceso(Tabla * tabla, int pid); 

//Retorna el time stamp
//Recibe: Puntero a la tabla, pid del proceso
//Devuelve: El timestamp del proceso
time_t getTimeStamp(Tabla * tabla, int pid);

//Resetea el timeStamp
//Recibe: Puntero a la tabla, pid del proceso
void resetTimeStamp(Tabla * tabla, int pid);

//Libera el codigo del proceso
//Recibe: Puntero a la tabla, pid del proceso
void liberarProcesoCodigo(Tabla * tabla, int pid);

//Se fija si esta suspendido o no
//Retorna: Suspendido ? 1 : 0
int suspendido(Tabla * tabla, int pid, char * pathImagen);

#endif /*LIBLIST_H_*/
